#pragma once
#ifndef SDK__INCLUDED__HH__
#define SDK__INCLUDED__HH__

#include <QEnvPrereqs.h>
#include <QEnvString.h>

namespace Lit
{
	namespace SdkTools
	{
		struct SysVar
		{
			std::string name;
			std::string value;

			SysVar( ){}
			SysVar( const SysVar& rk ) : name(rk.name), value(rk.value){}
			SysVar( const std::string &name_, bool grab_from_env = true, const std::string & value_ = "" ) : name( name_ ), value( grab_from_env?std::string(getenv( name.c_str() )):value_ ){}
			
			SysVar& operator=(const SysVar& rk){ name=rk.name; value=rk.value; return *this; }

			void capture( ){ if( !name.empty() ) { value = std::string(getenv( name.c_str() )); } }
		};
		class Config;
		class ConfigRef
		{
			friend class SdkConfig;
		protected:
			std::string mHome;
			std::string mLibraries;
			std::string mIncludes;
			std::string mName;
		public:
			ConfigRef(const ConfigRef&rk): mName(rk.mName), mHome(rk.mHome),mLibraries(rk.mLibraries),mIncludes(rk.mIncludes){}
			ConfigRef(const std::string name = "" ):mName(name){}
			ConfigRef(const std::string &name, const SysVar &home, const SysVar &lib=SysVar(), const SysVar &inc=SysVar() ) : mName(name), mHome(home.value), mLibraries(lib.value), mIncludes(inc.value){}
			ConfigRef(const std::string &name, const std::string &home, const std::string &lib="", const std::string &inc="" ) : mName(name), mHome(home), mLibraries(lib), mIncludes(inc){}
			virtual ~ConfigRef(){}
		
			
			void setPaths( const SysVar &home, const SysVar &lib=SysVar(), const SysVar &inc=SysVar() ){ mHome = home.value; mLibraries = lib.value; mIncludes=inc.value; }
			void setPaths( const std::string &home, const std::string &lib="", const std::string &inc="" ){ mHome = home; mLibraries = lib; mIncludes=inc; }

			const std::string& getHome() const{ return mHome; }
			const std::string& getLibraries() const{ return mLibraries; }
			const std::string& getIncludes() const{ return mIncludes; }
			const std::string& getName() const{ return mName; }
		
			void setHome(const std::string &str){ mHome=str; }
			void setLibraries(const std::string &str){ mLibraries=str; }
			void setIncludes(const std::string &str){ mIncludes=str; }
			void setName(const std::string &str){ mName=str; }

			void setHome(const SysVar &str){ mHome=str.value; }
			void setLibraries(const SysVar &str){ mLibraries=str.value; }
			void setIncludes(const SysVar &str){ mIncludes=str.value; }

			ConfigRef& operator=(const ConfigRef&rk){ mName=rk.mName; mHome=rk.mHome;mLibraries=rk.mLibraries;mIncludes=rk.mIncludes;return *this;}

		};
		class Config
		{
		public:
			typedef std::map<std::string, Config> Map;

		protected:
			std::string		mName;
			ConfigRef		mDebug;
			ConfigRef		mRelease;
			Map				mDeps;
		public:
			Config(const std::string &name = "" );
			Config(const Config& rk);
			virtual ~Config(void);
		
			Config& operator=( const Config& rk );

			const ConfigRef& getDebug() const;
			const ConfigRef& getRelease() const;
			ConfigRef& getDebug();
			ConfigRef& getRelease();
			
			bool hasDependency( const std::string &name ) const;
			Map& getDependencies();
			const Map& getDependencies() const;
			Config * getDependency( const std::string &name );
			const Config * getDependency( const std::string &name ) const;
			void addDependency( const Config& dep );
			void removeDependency( const std::string &name );

			void setName(const std::string &str);
			const std::string& getName() const;

			void update();
		};
	};
};

#endif